module sm_tb();

//include "tb_tasks.sv"

///////////////////////////////////////////////////////////////////////////////
////// SIGNALS AND DEFINITIONS
///////////////////////////////////////////////////////////////////////////////

//////////////////////////////////////
// Global Signals
//////////////////////////////////////
reg clk, rst_n;

//////////////////////////////////////
// Inputs to DP_DUT
//////////////////////////////////////
reg [13:0] Xmeas;
reg [13:0] cfg_data_lower;
logic [13:0] eep_rd_data;
reg [13:0] eep_rd_data_reg[0:3];

//////////////////////////////////////
// Inputs to SM_DUT
//////////////////////////////////////
reg[3:0] cfg_data_upper;
reg accel_vld;
reg frm_rdy;

//////////////////////////////////////
// Outputs from SM_DUT
//////////////////////////////////////
wire [1:0] eep_addr;

//////////////////////////////////////
// Outputs from DP_DUT
//////////////////////////////////////
wire [13:0] dst;
wire wrt_duty;


wire [1:0] BoothSel;

typedef enum logic [2:0] {PrevErr2Src0, SumErr2Src0, DutyWrk2Src0, EEP2Src0, 
							Xset2Src0, posAck2Src0, zero2Src0} src0sel_t;
typedef enum logic [2:0] {P2Src1, MultRes2Src1, Xmeas2Src1, CfgData2Src1,
							Err2Src1, zero2Src1} src1sel_t;


src1sel_t src1sel;
src0sel_t src0sel;

dig_dp DP_DUT(.clk(clk), .rst_n(rst_n), .Xmeas(Xmeas), 
		.cfg_data(cfg_data_lower), .eep_rd_data(eep_rd_data), 
		.src1sel(src1sel), .src0sel(src0sel), .cmplmnt(cmplmnt), 
		.saturate(saturate), .dst2P(dst2P), .dst2R(dst2R), .dst2Err(dst2Err), 
		.dst2PrevErr(dst2PrevErr), .dst2SumErr(dst2SumErr), 
		.dst2DutyWrk(dst2DutyWrk), .dst2Xset(dst2Xset), .dst(dst), 
		.BoothSel(BoothSel));


dig_sm SM_DUT(.clk(clk), .rst_n(rst_n), .accel_vld(accel_vld), 
			.eep_cs_n(eep_cs_n), .eep_r_w_n(eep_r_w_n), .eep_addr(eep_addr), 
			.src0sel(src0sel), .src1sel(src1sel), .cmplmnt(cmplmnt), 
			.saturate(saturate), .dst2P(dst2P), .dst2R(dst2R), 
			.dst2Err(dst2Err), .dst2PrevErr(dst2PrevErr), 
			.dst2SumErr(dst2SumErr), .dst2DutyWrk(dst2DutyWrk), 
			.dst2Xset(dst2Xset), .wrt_duty(wrt_duty), .BoothSel(BoothSel), 
			.chrg_pmp_en(chrg_pmp_en), .cfg_data(cfg_data_upper), 
			.strt_tx(strt_tx), .clr_rdy(clr_rdy), .frm_rdy(frm_rdy));

//////////////////////////////////////
// Other Misc. Work
//////////////////////////////////////
assign eep_rd_data = eep_rd_data_reg[eep_addr];
initial begin
	eep_rd_data_reg[0] = 14'h0123;
	eep_rd_data_reg[1] = 14'h0892;
	eep_rd_data_reg[2] = 14'h0189;
	eep_rd_data_reg[3] = 14'h0908;
end



///////////////////////////////////////////////////////////////////////////////
////// TEST BENCH CODE
///////////////////////////////////////////////////////////////////////////////

initial $monitor("SM_DUT.state: %h, wrt_dty: %h dst: %h, P_reg: %h , in_CM: %b , cfg_data:%h %h, time:%t", 
			SM_DUT.state,SM_DUT.dst2DutyWrk, dst, DP_DUT.P_reg, SM_DUT.in_CM, SM_DUT.cfg_data, DP_DUT.cfg_data, $time);


initial clk = 0;
always #5 clk = ~clk;

initial begin
	accel_vld = 0;
	Xmeas = 14'h0400;
	cfg_data_lower = 0;
	cfg_data_upper = 0;
	frm_rdy = 0;
end

initial begin
	rst_n = 0;
	@(posedge clk);
	@(posedge clk);
	rst_n = 1;
	$display("starting test");
	repeat(60) begin
		@(posedge clk)
		accel_vld = 0;
	end
	cfg_data_upper = 4'b0011;
	frm_rdy = 1;
	accel_vld = 1;
	@(posedge wrt_duty)
	$display("Output: %h", dst);
		
	repeat(10)
		@(posedge clk)
		accel_vld = 0;
		
	cfg_data_upper =4'b1001;
	cfg_data_lower = 14'h0696;
	repeat(10)
		@(posedge clk)
		accel_vld = 0;
	
	repeat(1000000000)
		@(posedge clk)
		frm_rdy = 0;
		
	$stop;
	

end


endmodule
